/**
 * @author        Nicolas Bottarini <nicolasbottarini@gmail.com>, 404 <http://www.proyecto404.com>
 * @version       $Rev: 3 $
 * @lastrevision  $Date: 2011-09-12 16:45:37 +0000 (Mon, 12 Sep 2011) $	 
 */
package com.proyecto404.core.ui.controls
{	
	import com.proyecto404.core.ui.BaseMovieClip;
	
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.text.TextField;

	public class Scrollbar extends BaseMovieClip
	{		
		public static const		SCROLL_SPEED		:	Number	=	10; // pixeles
		public static const		SCROLL_ACC			:	Number	=	1.1;
		public static const		SLIDER_FRICTION		:	Number	=	0.65;		
		
		public	var		content			:	DisplayObject;
		public	var		contentMask		:	Sprite;
		public	var		btnUp			:	Sprite;
		public	var		btnDown			:	Sprite;
		public	var		btnSlider		:	Sprite;
		public	var		dragRect		:	Rectangle;
		public	var		scrollDir		:	Number;
		public	var		currentSpeed	:	Number;
		public	var		sliderY			:	Number;
		public	var		contentY		:	Number;
		public	var		dragging		:	Boolean;
		public	var		clicking		:	Boolean;
		public	var		totalScroll		:	Number;
		
		public function ScrollBar(_content:DisplayObject, _mask:Sprite, _btnSlider:Sprite, _btnUp:Sprite = null, _btnDown:Sprite = null):void
		{
			content = _content;
			contentMask = _mask;
			btnSlider = _btnSlider;
			btnUp = _btnUp;
			btnDown = _btnDown;
			
			scrollDir = 0;
			currentSpeed = 0;
			dragging = false;
			clicking = false;
			contentY = content.y;
			
			if(btnUp != null && btnDown != null)
			{
				btnUp.buttonMode = true;
				btnUp.useHandCursor = true;
				btnDown.buttonMode = true;
				btnDown.useHandCursor = true;
				
				btnUp.addEventListener(MouseEvent.MOUSE_DOWN, scrollUp);
				btnUp.addEventListener(MouseEvent.MOUSE_UP, scrollStop);
				btnDown.addEventListener(MouseEvent.MOUSE_DOWN, scrollDown);
				btnDown.addEventListener(MouseEvent.MOUSE_UP, scrollStop);
			}
			
			if(btnSlider != null)
			{
				btnSlider.buttonMode = true;
				btnSlider.useHandCursor = true;		
				
				if(btnUp != null && btnDown != null)
				{
					dragRect = new Rectangle(btnSlider.x, btnUp.y, 0, btnDown.y - btnSlider.height - btnUp.y);
				}
				else
				{
					dragRect = new Rectangle(btnSlider.x, contentMask.y, 0, contentMask.height - btnSlider.height);
				}
				
				btnSlider.addEventListener(MouseEvent.MOUSE_DOWN, sliderPress);
				btnSlider.addEventListener(MouseEvent.MOUSE_UP, sliderRelease);
			}
			
			if(content is TextField)
			{
				TextField(content).mouseWheelEnabled = false;
			}
			
			content.stage.addEventListener(MouseEvent.MOUSE_UP, scrollStop);
			content.stage.addEventListener(MouseEvent.MOUSE_WHEEL, scrollWheel)
			
			this.addEventListener(Event.ENTER_FRAME, updateScroll);
		}
		
		public function scrollTo(pos:Number, animate:Boolean = false):void
		{
			if(!animate)
			{
				content.y = contentMask.y + pos;
			}
			else
			{
				contentY = contentMask.y + pos;
			}
		}
		
		public function destroy():void
		{
			if(btnUp != null && btnDown != null)
			{
				btnUp.removeEventListener(MouseEvent.MOUSE_DOWN, scrollUp);
				btnUp.removeEventListener(MouseEvent.MOUSE_UP, scrollStop);
				btnDown.removeEventListener(MouseEvent.MOUSE_DOWN, scrollDown);
				btnDown.removeEventListener(MouseEvent.MOUSE_UP, scrollStop);
			}
			
			if(btnSlider)
			{
				btnSlider.removeEventListener(MouseEvent.MOUSE_DOWN, sliderPress);
				btnSlider.removeEventListener(MouseEvent.MOUSE_UP, sliderRelease);
			}
			content.stage.removeEventListener(MouseEvent.MOUSE_UP, scrollStop);
			content.stage.removeEventListener(MouseEvent.MOUSE_WHEEL, scrollWheel)
			this.removeEventListener(Event.ENTER_FRAME, updateScroll);
		}
		
		private function updateScroll(e:Event):void
		{
			
			totalScroll = content.height - contentMask.height;
			
			if(dragging)
			{
				if(btnSlider != null) contentY = contentMask.y + (btnSlider.y - dragRect.y) / dragRect.height * -totalScroll;
			}
			else if(clicking)
			{
				currentSpeed *= SCROLL_ACC;
				contentY = content.y + currentSpeed * scrollDir;
			}
			
			if(contentY + content.height < contentMask.y + contentMask.height)
			{
				contentY = contentMask.y + contentMask.height - content.height;
			}
			
			if(contentY > contentMask.y)
			{
				contentY = contentMask.y;
			}
			
			content.y += (contentY - content.y) / 3;
			
			if(!dragging && btnSlider != null)
			{
				sliderY = (contentY - contentMask.y) / -totalScroll * dragRect.height + dragRect.y;
				btnSlider.y += (sliderY - btnSlider.y) / 3;
			}
			
		}
		
		private function scrollUp(e:MouseEvent):void
		{
			scrollDir = 1;
			currentSpeed = SCROLL_SPEED;
			clicking = true;
		}
		
		private function scrollDown(e:MouseEvent):void
		{
			scrollDir = -1;
			currentSpeed = SCROLL_SPEED;
			clicking = true;
		}
		
		private function scrollWheel(e:MouseEvent):void
		{
			if(e.target == content)
			{
				if(e.delta > 0)
				{
					contentY += SCROLL_SPEED * 2;
				}
				else
				{
					contentY -= SCROLL_SPEED * 2;
				}
			}
		}
		
		private function scrollStop(e:MouseEvent):void
		{
			sliderRelease();
			clicking = false;
		}
		
		private function sliderPress(e:MouseEvent):void
		{
			if(btnSlider != null) btnSlider.startDrag(false, dragRect);
			dragging = true;
		}
		
		private function sliderRelease(e:MouseEvent = null):void
		{
			if(btnSlider != null) btnSlider.stopDrag();
			dragging = false;
		}
		
	}
	
}